﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.Routing;

namespace Songhay.Web.Mvc.Extensions
{
    /// <summary>
    /// TagBuilder Extension Methods meant to streamline its use.
    /// </summary>
    /// <remarks>
    /// See also:
    /// “ASP.NET MVC: TagBuilder Extension Methods”
    /// http://mo.notono.us/2009/07/aspnet-mvc-tagbuilder-extension-methods.html
    /// </remarks>
    public static class TagBuilderExtensions
    {

        /// <summary>
        /// Similarly to <see cref="M:TagBuilder.MergeAttributes"/> merges the attributes passed to it but 
        /// accepts the attributes in the form of an anonymous object, and also returns the <see cref="TagBuilder"/> 
        /// instance, allowing chaining.
        /// </summary>
        /// <param name="tb">The <see cref="TagBuilder"/> instance to extend.</param>
        /// <param name="tagAttributes">The tag attributes.</param>
        /// <returns>
        /// The same <see cref="TagBuilder"/> instance
        /// </returns>
        public static TagBuilder WithAttributes(this TagBuilder tb, object tagAttributes)
        {
            tb.MergeAttributes(new RouteValueDictionary(tagAttributes));
            return tb;
        }

        /// <summary>
        /// Similarly to <see cref="M:TagBuilder.AddCssClass"/> adds inner Html but also returns the 
        /// <see cref="TagBuilder"/> instance, allowing chaining.
        /// </summary>
        /// <param name="tb">The <see cref="TagBuilder"/> instance to extend.</param>
        /// <param name="cssClass">The CSS class.</param>
        /// <returns>
        /// The same <see cref="TagBuilder"/> instance
        /// </returns>
        public static TagBuilder WithCssClass(this TagBuilder tb, string cssClass)
        {
            tb.AddCssClass(cssClass);
            return tb;
        }

        /// <summary>
        /// Similarly to <see cref="M:TagBuilder.GenerateId"/> generates the Id of the tag, but also
        /// returns the <see cref="TagBuilder"/> instance, allowing chaining.
        /// </summary>
        /// <param name="tb">The <see cref="TagBuilder"/> instance to extend.</param>
        /// <param name="name">The name.</param>
        /// <returns>
        /// The same <see cref="TagBuilder"/> instance
        /// </returns>
        public static TagBuilder WithGeneratedId(this TagBuilder tb, string name)
        {
            tb.GenerateId(name);
            return tb;
        }

        /// <summary>
        /// Similarly to <see cref="P:TagBuilder.IdAttributeDotReplacement"/> sets the id attribute dot replacement of the tag, 
        /// but also returns the <see cref="TagBuilder"/> instance, allowing chaining.
        /// </summary>
        /// <param name="tb">The <see cref="TagBuilder"/> instance to extend.</param>
        /// <param name="idAttributeDotReplacement">The id attribute dot replacement.</param>
        /// <returns>
        /// The same <see cref="TagBuilder"/> instance
        /// </returns>
        public static TagBuilder WithIdAttributeDotReplacement(this TagBuilder tb, string idAttributeDotReplacement)
        {
            tb.IdAttributeDotReplacement = idAttributeDotReplacement;
            return tb;
        }

        /// <summary>
        /// Similarly to <see cref="P:TagBuilder.InnerHtml"/> sets the inner Html of the tag, but also returns 
        /// the <see cref="TagBuilder"/> instance, allowing chaining.
        /// </summary>
        /// <param name="tb">The <see cref="TagBuilder"/> instance to extend.</param>
        /// <param name="innerHtml">The inner HTML.</param>
        /// <returns>
        /// The same <see cref="TagBuilder"/> instance
        /// </returns>
        public static TagBuilder WithInnerHtml(this TagBuilder tb, string innerHtml)
        {
            tb.InnerHtml = innerHtml;
            return tb;
        }

        /// <summary>
        /// Similarly to <see cref="M:TagBuilder.SetInnerText"/> sets the inner text of the tag, but also returns 
        /// the <see cref="TagBuilder"/> instance, allowing chaining.
        /// </summary>
        /// <param name="tb">The <see cref="TagBuilder"/> instance to extend.</param>
        /// <param name="innerText">The inner text.</param>
        /// <returns>
        /// The same <see cref="TagBuilder"/> instance
        /// </returns>
        public static TagBuilder WithInnerText(this TagBuilder tb, string innerText)
        {
            tb.SetInnerText(innerText);
            return tb;
        }
    }
}
